home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / MATH.SWG / 0061_EQUATION parser.pas < prev    next >
Pascal/Delphi Source File  |  1994-01-27  |  6KB  |  213 lines

  1. {
  2. > I'm currently working on a small program for a Turbo Pascal class
  3. > I am taking.  The assignment is to write a program that solves a system
  4. > of equations via Cramer's Rule.  For example:
  5. >
  6. > 4x - 3y + 9z = 21
  7. > 5x - 43y - 3z = 45
  8. > 34x - 394y + 32z = 9
  9. >
  10. > and then find values for x, y, and z.
  11. >
  12. >    Now this is no problem:  I simply get input into a 3 x 4 array, which
  13. > would look like this for the sample above:
  14. >
  15. > 4    -3     9     21
  16. > 5    -43    -3    45
  17. > 34   -394   32    9
  18. >
  19. >    The problem I am having is getting this input from the user.  Now I
  20. > have thought of a few ways to accomplish this, namely:
  21. >
  22. > (1) Ask the user to enter the coefficients and the answer on a line and
  23. > hit return, and do this for each equation--this method allows me to put the
  24. > data directly into the array.
  25. >
  26. > (2) Give a rigid example of how and where to enter the equation, for
  27. > example #####x(sign)#####y(sign)#####z = #####
  28. > so I know where to read for the values to put into the array.
  29. >
  30. > (3) Possibly use the Val procedure and ask the user to input all number
  31. > as in #1, but separate the numbers with dashes.
  32. >
  33. > (4) Possibly convert string values to their ascii equivalent, and see if
  34. > they are numbers, turning non numbers into spaces.
  35. >
  36. > But, what I would rather do is to prompt the user for the whole equation
  37. > and have him/her type it out naturally and then pick the numbers out of
  38. > it to put into the 3x4 array.  Example:
  39. >
  40. > Enter equation #1:
  41. > 3x + 4y - 8z = 45
  42. > ...
  43. >
  44. >    This would seem to require storing the input as a string, and as far
  45. > as I know, you can't pick values of a string (except in a limited sense
  46. > with the Val function as touched upon above).  But I think that it has
  47. > to be possible for me to process a naturally typed out equation!  And I
  48. > would appreciate pointers to that effect.
  49.  
  50. The following code, written in Turbo Pascal 6, should do what you
  51. want. You may want to test it more thoroughly than I did, and tidy up
  52. the code a bit. It checks for validity of input. Values are stored as
  53. reals.
  54.  
  55. It reads in the equation, and puts the values into the global array
  56. eq_array.
  57. }
  58.  
  59. program input_equations(input, output);
  60.  
  61. type
  62.   eq_string = string[40];
  63.  
  64. var
  65.   instr :eq_string;
  66.   eq_array :array [1..3, 1..4] of real;
  67.   eq_num :byte;
  68.   x, y, z, answer :real;
  69.   eq_ok :boolean;
  70.  
  71.  
  72. procedure prepare_equation_string (var s :eq_string);
  73. { Removes spaces and converts all letter to upper case }
  74. var
  75.   tempstr :eq_string;
  76.   n :byte;
  77. begin
  78.   tempstr := '';
  79.   for n := 1 to length(s) do
  80.     if s[n] <> ' ' then tempstr := tempstr + upcase(s[n]);
  81.   s := tempstr
  82. end;
  83.  
  84. function get_arguments (s :eq_string; var a1, a2, a3 :eq_string) :boolean;
  85. { Splits equation into argument.
  86.   eg, if s='3X+4Y-Z', then a1='3X', a2='+4Y', a3='-Z'.
  87.  
  88. If any argument is blank, or there are more than 3 arguments,
  89. returns FALSE, otherwise returns TRUE }
  90.  
  91.   function next_arg (s :eq_string) :eq_string;
  92.   var
  93.     n :byte;
  94.   begin
  95.     n := 2;
  96.     while (n <= length(s)) and not (s[n] in ['+', '-']) do
  97.       inc (n);
  98.     next_arg := copy (s, 1, n-1);
  99.   end;
  100.  
  101. begin
  102.   a1 := next_arg (s);
  103.   delete (s, 1, length(a1));
  104.   a2 := next_arg (s);
  105.   delete (s, 1, length(a2));
  106.   a3 := next_arg (s);
  107.   delete (s, 1, length(a3));
  108.   get_arguments := ((length(a1)*length(a2)*length(a3)) > 0) and
  109.                    (s = '')
  110. end;
  111.  
  112. function assign_values (var x, y, z :real; a1, a2, a3 :eq_string) :boolean;
  113. var
  114.   x_assigned, y_assigned, z_assigned, ok_so_far :boolean;
  115.  
  116.     function assign_value (s :eq_string) :boolean;
  117.     var
  118.       id :char;
  119.       value :real;
  120.       resultcode :integer;
  121.       ok :boolean;
  122.     begin
  123.       id := s[length(s)];
  124.       delete (s, length(s), 1);
  125.       if (s = '') or (s = '+') then
  126.         s := '1';
  127.       if s = '-' then
  128.         s := '-1';
  129.       val (s, value, resultcode);
  130.       ok := (resultcode = 0);
  131.       case id of
  132.         'X' : begin
  133.                 x := value;
  134.                 x_assigned := true
  135.               end;
  136.         'Y' : begin
  137.                 y := value;
  138.                 y_assigned := true
  139.               end;
  140.         'Z' : begin
  141.                 z := value;
  142.                 z_assigned := true
  143.               end
  144.       else
  145.         ok := false
  146.       end;
  147.       assign_value := ok
  148.     end;
  149.  
  150. begin
  151.   x_assigned := false;
  152.   y_assigned := false;
  153.   z_assigned := false;
  154.   ok_so_far  := assign_value (a1);
  155.   ok_so_far  := ok_so_far and assign_value (a2);
  156.   ok_so_far  := ok_so_far and assign_value (a3);
  157.   assign_values := ok_so_far and x_assigned and y_assigned and z_assigned;
  158. end;
  159.  
  160. function extract_values(s : eq_string; var x, y, z, ans : real) : boolean;
  161. var
  162.   ok_so_far : boolean;
  163.   n : byte;
  164.   lhs, rhs,
  165.   a1, a2, a3 : eq_string;
  166.   resultcode : integer;
  167.  
  168. begin
  169.   ok_so_far := true;
  170.   prepare_equation_string(s);
  171.   n := pos ('=', s);
  172.   if n = 0 then
  173.     ok_so_far := false                     { No = in equation }
  174.   else
  175.   begin
  176.     rhs := copy (s, n+1, length(s)-n);
  177.     if pos ('=', rhs) > 0 then
  178.       ok_so_far := false                 { More than one = in equation }
  179.     else
  180.     begin
  181.       lhs := copy (s, 1, n-1);
  182.       if (lhs = '') or (rhs = '') then
  183.         ok_so_far := false             { At least one side of equation }
  184.       else                             { is blank }
  185.       begin
  186.         ok_so_far := get_arguments (lhs, a1, a2, a3);
  187.         ok_so_far := ok_so_far and assign_values (x, y, z, a1, a2, a3);
  188.         val (rhs, ans, resultcode);
  189.         ok_so_far := ok_so_far and (resultcode = 0)
  190.       end;
  191.     end;
  192.   end;
  193.   extract_values := ok_so_far;
  194. end;
  195.  
  196. begin
  197.   for eq_num := 1 to 3 do
  198.   begin
  199.     repeat
  200.       write ('Equation ', eq_num, ': ');
  201.       readln (instr);
  202.       eq_ok := extract_values (instr, x, y, z, answer);
  203.       if not eq_ok then
  204.         writeln ('Equation not in suitable format, try again');
  205.     until eq_ok;
  206.     eq_array [eq_num, 1] := x;
  207.     eq_array [eq_num, 2] := y;
  208.     eq_array [eq_num, 3] := z;
  209.     eq_array [eq_num, 4] := answer;
  210.   end;
  211. end.
  212.  
  213.